 package com.iaz.tech.tools.ai.neuron.cell;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.iaz.tech.tools.ai.neuron.ability.ICommunicateAbility;
import com.iaz.tech.tools.ai.neuron.ability.INeuronAbility;
import com.iaz.tech.tools.ai.neuron.runtime.INeuronRuntimeAbility;
import com.iaz.tech.tools.message.IMessageAble;
import com.iaz.tech.tools.message.impl.MessageForTalk;
import com.iaz.tech.tools.mq.AZIMessageContainer;
import com.iaz.tech.tools.mq.IMessageSectionAbility; 

import lombok.Data;
import lombok.EqualsAndHashCode;

/**
 * 神经元中枢，神经元用于进行通信
 * 通过调用IMessageAble 的接口进行处理
 * 
 * 每个神经元，都有若干NerveCenter
 * 实现： 神经元与神经元的通讯
 * 
 * 这个是存储神经元之间通信用。
 * 
 * 这是进行远程通信，才采用神经元，
 * 
 */
@EqualsAndHashCode(callSuper=false)
@Data
public class NerveCenter extends Neuron implements ICommunicateAbility {
	
	/**
	 * 神经元节点
	 */
	private List<UUID> neurons = new ArrayList<UUID>();
	 
	/**
     * 日志
     */
	private final static Logger logger = (Logger) LoggerFactory.getLogger(NerveCenter.class);
	
	/**
	 * talk 方法
	 * 用于进行神经元之间的通讯
	 * 
	 * @param neuronID 目标神经元ID
	 * @param message  消息
	 * @return
	 */
	@Override
	public IMessageAble talk(UUID neuronID, IMessageAble message) {
		IMessageAble result = null;
		try {
			if (neuronID == null) {
				throw new Exception("入口参数neuronID 为空，或者没有指明！");
			}
			
			if (this.getRuntime() == null) {
				throw new Exception("没有Rumtime执行！");
			}
			
			if (this.getRuntime().findMQ() == null) {
				throw new Exception("系统内置的Message Queue 没有发现。" );
			}
			
			if (message == null) {
				throw new Exception("Message 没有指定。");
			}

			UUID tmpNeuronID = null;

			for (int i = 0; i < this.neurons.size(); i++ ) {
				UUID neuron_id = this.neurons.get(i);
				if (neuron_id == null){
					continue;
				}
				if (!neuronID.equals(neuron_id)){
					continue;
				}
				tmpNeuronID = neuron_id;
				break;
			}
			if (tmpNeuronID == null) {
				return result; 
			}
			
			IMessageSectionAbility messageQueue = this.getRuntime().findMQ();
			/* 填充信息 */
			messageQueue.pushMessage(tmpNeuronID, message);
			/* 填充Talk信息 */
			result = new MessageForTalk();
			result.setMessage("信息发送成功！");
			
			return result;
		} catch(Exception e) {
			logger.error("出现异常：" + e.getMessage());
			result = null;
		}
		return result;
	}
	/**
	 * putCommunication 方法
	 * 用于将神经元添加到神经元中枢中
	 */
	@Override
	public void putCommunication(IMessageSectionAbility neuron) {
		try {
			if (neuron == null) {
				throw new Exception("入口参数neuron 为空，或者没有指定。");
			}

			if (neuron instanceof INeuronAbility) {
				INeuronAbility neuronAbility = (INeuronAbility)neuron;
				this.neurons.add(neuronAbility.forNeuronID());
			} 
		} catch(Exception e) {
			logger.error("出现异常：" + e.getMessage());
		}		
	}

	@Override
	public boolean exists(List<UUID> targetNeurons) {
		boolean result = false;
		try {
			if (targetNeurons == null) {
				throw new Exception("入口参数targetNeurons 为空，或者没有指定。");
			}
			for (int i = 0; i < targetNeurons.size(); i++) {
				UUID neuronID = targetNeurons.get(i);
				if (neuronID == null) {
					continue;
				}
				if (this.neurons.contains(neuronID)) {
					result = true;
					break;
				}
			}
		} catch(Exception e) {
			logger.error("出现异常：" + e.getMessage());
		}	
		return result;
	}
	/**
	 * answer 方法
	 * 用于从神经元中枢中获取消息
	 */
	@Override
	public List<IMessageAble> answer(UUID id) {
		List<IMessageAble> result = new ArrayList<IMessageAble>();
		try {
			if (id == null) {
				throw new Exception("入口参数id 为空，或者没有指定。");
			}
			if (this.getRuntime() == null) {
				throw new Exception("没有Rumtime执行！");
			}
			
			if (this.getRuntime().findMQ() == null) {
				throw new Exception("系统内置的Message Queue 没有发现。" );
			}
			
			UUID tmpNeuronID = null;

			for (int i = 0; i < this.neurons.size(); i++ ) {
				UUID neuron_id = this.neurons.get(i);
				if (neuron_id == null){
					continue;
				}
				if (!id.equals(neuron_id)){
					continue;
				}
				tmpNeuronID = neuron_id;
				break;
			}
			if (tmpNeuronID == null) {
				return result; 
			} 
			IMessageSectionAbility messageQueue = this.getRuntime().findMQ();
			List<IMessageAble> msgs = messageQueue.getMessages(id);
			if (msgs != null) {
				result.addAll(msgs);
			}
			return result;
		} catch(Exception e) {
			logger.error("异常：" + e.getMessage());
			result.clear();
		}
		return result;
	}

	/**
	 * 多任务执行
	 */
	@Override
	public void execute(Object sender) {
		try {
			/* 调整消息队列 */
			((AZIMessageContainer)this.getRuntime().findMQ()).scanMessagesForTime(this.getNeuronId());
		} catch(Exception e) {
			logger.error("出现异常：" + e.getMessage());
		}
	}

	@Override
	public void stop() {
		try {
			/* 停止消息队列 */
			((AZIMessageContainer)this.getRuntime().findMQ()).stopMessagesForTime(this.getNeuronId());
		} catch(Exception e) {
			logger.error("出现异常：" + e.getMessage());
		}
	}
	
}
